package com.leeon.thread;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import static net.mindview.util.Print.print;

class SleepBolcked implements Runnable{

	@Override
	public void run() {
		try {
			TimeUnit.SECONDS.sleep(100);
		} catch (InterruptedException e) {
			print("InterruptedException");
		}
	}
	
}

class IOBlocked implements Runnable{
	
	private InputStream in;
	
	public IOBlocked(InputStream in) {
		this.in = in;
	}

	@Override
	public void run() {
		try {
			print("waiting for read()");
			in.read();
		} catch (IOException e) {
			if(Thread.currentThread().isInterrupted()) {
				print("interrupted from block");
			}else {
				throw new RuntimeException();
			}
		}
		print("exiting ioblocked.run()");
	}
	
}

class SynchronizedBlocked implements Runnable{

	public SynchronizedBlocked() {
		new Thread() {
			@Override
			public void run() {
				f();
			}
		}.start();
	}
	
	public synchronized void f() {
		while(true)Thread.yield();
	}
	
	@Override
	public void run() {
		print("trying to call t");
		f();
		print("exiting synchronizedblocked.run()");
	}
	
}

public class Interrupting {
	private static ExecutorService exec = Executors.newCachedThreadPool();
	static void test(Runnable r) throws InterruptedException {
		Future<?> f = exec.submit(r);
		TimeUnit.MILLISECONDS.sleep(100);
		print("Interrupting " + r.getClass().getName());
		f.cancel(true);
		print("Interrupt sent to " + r.getClass().getName());
	}
	
	public static void main(String[] args) throws InterruptedException {
		test(new SleepBolcked());
		test(new IOBlocked(System.in));
		test(new SynchronizedBlocked());
		TimeUnit.SECONDS.sleep(10);
		print("Aborting with System.exit(0)");
		System.exit(0);
	}
}
